package wangwenjun.phase2.concurrencypattern.readwritelockseparation.demo01;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import util.ThreadUtil;

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

/**
 * @author ChangLiang
 * @date 2020/6/12
 */
@Slf4j
public class AppTest {

    private final static String text = "abcdefghijklmnopqrstuvwxyz";

    @Test
    @DisplayName("test fixed sleep")
    public void test() throws InterruptedException {
        // 共享数据
        final ShareData shareData = new ShareData(20);

        ThreadUtil.sleepForMilliSeconds(10_000);

        // 2个write thread 每3秒写一次 每次写耗时1秒
        IntStream.range(0, 2).forEach(i -> new Thread(()->{
            while (true) {
                for (int index = 0; index < text.length(); index++) {
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    try {
                        char c = text.charAt(index);
                        shareData.write(c);
                        log.warn("{} write {}" , Thread.currentThread(), c);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"write-thread-"+i).start());

        // 10个read thread 不停地读 每1s读一次 每次读耗时1s 需要修改ShareData#read
        IntStream.range(0,10).forEach(i->new Thread(()->{
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    log.info("{} read {}", Thread.currentThread(), shareData.read());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "read-thread-"+i).start());

        Thread.currentThread().join();
    }

    @Test
    @DisplayName("test")
    public void test2() throws InterruptedException {
        // 共享数据
        final ShareData shareData = new ShareData(20);

        ThreadUtil.sleepForMilliSeconds(10_000);

        // 2个write thread 每2~3秒写一次 每次写耗时1秒
        IntStream.range(0, 2).forEach(i -> new Thread(()->{
            while (true) {
                for (int index = 0; index < text.length(); index++) {
                    try {
                        TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(2,3));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    try {
                        char c = text.charAt(index);
                        shareData.write(c);
                        log.warn("{} write {}" , Thread.currentThread(), c);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"write-thread-"+i).start());

        // 10个read thread 不停地读 每500~1000ms读一次 每次读耗时200ms
        IntStream.range(0,10).forEach(i->new Thread(()->{
            while (true) {
                try {
                    TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(500,1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    log.info("{} read {}", Thread.currentThread(), shareData.read());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "read-thread-"+i).start());

        Thread.currentThread().join();
    }
}
